-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
full_posix_sockets #7672
full_posix_sockets #7672
Conversation
473d614
to
bbf53ca
Compare
96f6dff
to
d36f897
Compare
This PR would now be good to land, but this is producing some errors on the upstream bots that I do not understand, and am unable to reproduce. @kripken Does any of that make sense to you? |
I can reproduce those errors locally, using the LLVM wasm backend. E.g.
|
Hmm, I wonder why that would occur only on the wasm backend.. Those symbols are moved from |
Oh, perhaps I need to also update the libc.symbols and wasm-libc.symbols files, let's see if that does it. |
80189a4
to
52ce4d5
Compare
Updated this PR and it now passes. Ready for a second review? |
024f446
to
38eb8f7
Compare
I don't understand the motivation here yet. What does "proxy" mean - what is proxied where? Is this related to threading proxying? |
Proxying here means that instead of implementing the POSIX sockets calls in the browser, each sockets API call is serialized out via WebSockets pipe over to a native "websockify" style intermediate process, which natively performs those exact sockets calls, and returns the results back - making the Emscripten page look like it has full sockets API access available to it. In order to pull it off, it does require threading proxying, because this only works in multithreaded PROXY_TO_PTHREAD builds, since the command proxying is synchronous. |
Updated this PR, and it now looks green to merge. Good for a review pass? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, so this lets you use normal C sockets code, and it synchronously proxies commands to a websockets server that does the actual sockets operations? And you say it's useful for things like test harnesses etc. - this seems like quite a lot of work for just that? I feel like I'm missing the use case.
Emscripten provides a native POSIX Sockets proxy server program, located in directory tools/websocket_to_posix_proxy/, that allows full POSIX Sockets API access from a web browser. This support works by proxying all POSIX Sockets API calls from the browser to the Emscripten POSIX Sockets proxy server (via transparent use of WebSockets API), and the proxy server then performs the native TCP/UDP calls on behalf of the page. This allows a web browser page to run full TCP & UDP connections, act as a server to accept incoming connections, and perform host name lookups and reverse lookups. Because all API calls are individually proxied, this support can be slow. This support is mostly useful for developing testing infrastructure and debugging. | ||
|
||
For an example of how the POSIX Sockets proxy server works in an Emscripten client program, see the file tests/websocket/tcp_echo_client.cpp. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docs don't seem to mention the new proxy option from this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated docs with linker settings for each case.
system/lib/libc.symbols
Outdated
@@ -1,310 +1,541 @@ | |||
-------- C h_errno | |||
-------- C __hwcap |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this diff so large? I think the symbols should be sorted - maybe you didn't sort them before applying?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an as-is result from calling llvm-nm on new generated libc.bc. Is there some special process that one must do instead of dumping them? Perhaps there should be an automatic script that updates the symbol files from already built cache?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably add a script, but basically just pipe it through | sort
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah gotcha, updated the symbols files (using embuilder to build them, then llvm-nm ~/.emscripten_cache/asmjs/libc.bc | sort > system/lib/libc.symbols
LIBC_SOCKETS = ['socket.c', 'socketpair.c', 'shutdown.c', 'bind.c', 'connect.c', | ||
'listen.c', 'accept.c', 'getsockname.c', 'getpeername.c', 'send.c', | ||
'recv.c', 'sendto.c', 'recvfrom.c', 'sendmsg.c', 'recvmsg.c', | ||
'getsockopt.c', 'setsockopt.c', 'freeaddrinfo.c'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are included in those builds - so what is proxied here, the syscalls called by those?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These different API calls are proxied through a WebSocket server. I.e. instead of socket() calling musl which calls socketcall(), the musl functions are replaced with C implemented functions that proxy each call through the WebSockets bridge.
We use this to target an existing sockets utilizing debug suite over to HTML5, retaining the same codebase for portability. This lets one reuse existing POSIX sockets code as is, and one only needs to add one API call at the start of the program to the bridge server, and then you get full sockets. This way we are able to locally connect a Unity page to all sorts of existing harness tools that are running on local developer's machine (e.g. debugger, profiler, inspector) |
0e6b9d9
to
9542cc6
Compare
53706a7
to
499dcff
Compare
Thanks, good pointer, followed that pattern and added a sockets tests suite, which seems to pass nicely. |
Yeah, I think I did end up fixing this one, and I can follow up with a PR and test case after this lands. |
This is the server application that proxies socket calls made by clients over websockets to the native system. I've successfully used this, for example, to play a video stream over HTTP using FFplay compiled to WebAssembly. |
Ping @kripken for approval? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm with switching to upstream as mentioned in the comment.
hopefully these tests are not flakey, but if they are, we can revisit this later...
CHROME_FLAGS_NOCACHE: "--disk-cache-dir=/dev/null --disk-cache-size=1 --media-cache-size=1 --disable-application-cache --incognito" | ||
command: | | ||
export EMTEST_BROWSER="/usr/bin/google-chrome $CHROME_FLAGS_BASE $CHROME_FLAGS_HEADLESS $CHROME_FLAGS_WASM $CHROME_FLAGS_NOCACHE" | ||
python tests/runner.py sockets | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wish there was a way to share this code instead of copying it, but I'm not sure if there is in circleci...
be08762
to
4b8208b
Compare
Test failures are unrelated, looks like LLVM has added indentation checking to freetype code. |
Hey you guys, I'm working on something that uses POSIX, and I am still getting I'm not sure if I can actually get around this or not. |
|
* Add posix sockets proxying option. * Add test for emscripten_websocket_get_url_length(). * Update docs on which sockets functions are proxied * Add sockets tests for chrome * Install websockets before sockets test run * Install node before ws * Try to fix ws installation * Fix websocket send test * Fix bad _strlen dep in _formatString function. * Add formatString dep
Update `test_websocket_send.c` such that it checks that both text and binary messages are received. Also, delete `websocket.c` which I think was supposed to be removed as part of emscripten-core#7672 (where it was renamed to test_websocket_send.c). Fixes: emscripten-core#21515
It appears that ever since 31309a8 "full_posix_sockets (emscripten-core#7672)", the _proxy side sent back a result that included an explicit option_len while the _socket side computes that value from the overall result size.
…socket.c ...that appears to have been bogus ever since 31309a8 "full_posix_sockets (emscripten-core#7672)"
This adds full POSIX sockets API support via a
-s PROXY_POSIX_SOCKETS=1
option. This is implemented by proxying out the sockets API calls to a separate proxy bridge process running on localhost. (that one needs to separately spawn)This can be useful for special occassions, e.g. when building unit test harnesses or similar, where one just wants to compile existing POSIX sockets code and "have it work" locally. A web browser page can then be simulated to act as a TCP or UDP server, for example.
The feature builds on top of #7670, and can only land after #7670 lands.
Will need splitting out libc to two .bc library parts, one for proxy sockets variant, and another one with the musl stubs.